package Controllers

import (
	"Volta/App/Common/Constant/Errorcode"
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"gopkg.in/go-playground/validator.v9"
	"github.com/gin-gonic/gin"
	"time"
)
//-------------------接口统一的读取客户端传递的数据并自动解码成结构体且自动进行validate的验证-------------------------------------
/**
 * 将请求的body转换为request数据结构
 * @param c
 * @param wspl  传入request数据结构的指针 如 new(FastRequest)
 * @author sam@2020-04-07 11:25:08
 */
func GenRequest(c *gin.Context, request interface{}) (err error) {
	//读取客户端传递的json格式的body
	body, err := ReadBody(c)
	if err != nil {
		return
	}
	//json解码
	err = json.Unmarshal(body, request)
	if err == nil {
		validate := validator.New()
		errValidate := validate.Struct(request)
		if errValidate != nil {
			return errValidate
		}
	}
	return err
}
//重复读取body
//@reviser sam@2020-04-07 11:41:23
func ReadBody(c *gin.Context) (body []byte, err error) {
	// ReadAll 读取 r 中的所有数据，返回读取的数据和遇到的错误。 如果读取成功，则 err 返回 nil，而不是 EOF，因为 ReadAll 定义为读取所有数据，所以不会把 EOF 当做错误处理。
	body, err = ioutil.ReadAll(c.Request.Body)
	if err != nil {
		return
	}
	//包装一个io.Reader，返回一个io.ReadCloser
	c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
	return
}
//----------------------接口统一的成功时返回方法------------------------------------------------------
/**
 * 接口统一的正确返回值
 *  Success(c, "sam is a good man.")
 *  Success(c,samStruct)
 *  Success(c,samMap)
 * @reviser sam@2020-04-07 10:30:16
 */
func Success(c *gin.Context, data interface{}) {
	c.JSON(http.StatusOK, gin.H{
		"code":        Errorcode.Success,//200
		"msg":         "ok",
		"time":        time.Now(),
		"request_uri": c.Request.URL.Path,
		"data":        data,
	})
	c.Abort()
}
//--------------------------------- 接口统一的以及定制的失败时返回方法 ------------------------------------------
/**
 * 失败时返回方法,注意http状态码仍然是200，只是业务状态码code有所不同
 * Error(c,400, "路由不存在")
 * Error(c,500)
 * @todo 注意这里的code是业务代码,http code始终是200
 * @reviser sam@2020-04-07 10:32:17
 */
func Error(c *gin.Context, code int, msg ...string) {
	//获取错误信息
	message := ""
	if len(msg) > 0 {
		message = msg[0]
	} else {
		message = Errorcode.GetMsg(code)
	}

	c.JSON(http.StatusOK, gin.H{
		"code":        code,
		"msg":         message,
		"time":        time.Now(),
		"request_uri": c.Request.URL.Path,
		"data":        make(map[string]string),
	})
	c.Abort()
}

func Error404(c *gin.Context) {
	Error(c, Errorcode.NotFound, "路由不存在")
}

func Error500(c *gin.Context) {
	Error(c, Errorcode.SystemError,"网络异常")
}
//------------------------------------------------------------------------------

type HTTPError struct {
	Code    int    `json:"code" example:"400"`
	Message string `json:"message" example:"status bad wspl"`
}


